package com.kitty.game.activity.service.time;

import com.kitty.common.utils.SpringUtils;
import com.kitty.game.achieve.body.BossImgType;
import com.kitty.game.activity.service.ActivityHandler;
import com.kitty.game.boss.service.NewBossService;
import com.kitty.game.chat.service.ChatService;
import com.kitty.game.config.MapBossPos;
import com.kitty.game.config.NPC;
import com.kitty.game.enter.Position;
import com.kitty.game.fight.bean.Fight;
import com.kitty.game.mail.model.Mail;
import com.kitty.game.npc.service.NewNpcService;
import com.kitty.game.player.model.BossImgInfos;
import com.kitty.game.role.model.Role;
import com.kitty.game.team.model.Member;
import com.kitty.game.team.model.Team;
import com.kitty.game.team.service.TeamService;
import com.kitty.game.utils.Const;
import com.kitty.game.utils.TimeUtil;
import com.kitty.listener.event.FightEndEvent;
import com.kitty.mina.task.ThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.nutz.json.Json;
import org.nutz.json.JsonFormat;
import org.nutz.lang.util.NutMap;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ThreadLocalRandom;
@Slf4j
public abstract class FightActivityHandler extends ActivityHandler {
    @Autowired
    protected TeamService teamService;
    @Autowired
    protected NewBossService bossService;
    @Autowired
    protected NewNpcService npcService;
    @Autowired
    ChatService chatService;
    /**获取NPC对话内容*/
    protected abstract String getNpcContent(Role role, NPC bossNpc);
    /**获得不能开始战斗的内容*/
    protected abstract String getNpcContentNotFight(Role role, NPC bossNpc);
    /**触发战斗*/
    protected abstract void doStartFight(Role role, NPC bossNpc);

    protected abstract int getFightType(Role role);
    protected abstract NPC getBossNpc(int npcId);
    protected abstract void clearNpcAfterWin(Role role, NPC bossNpc);
    protected abstract void giveReward(Role role, FightEndEvent fightEndEvent, NPC bossNpc);
    protected abstract void clearNpcTimeOut(NPC npc);

    /**已经使用的对应地图的位置*/
    private static Map<Integer, List<Position>> usedPotions = new ConcurrentHashMap<>();

    /**获得地图内的一个没有使用的随机位置*/
    protected Position getRandomPosition(int mapId) {
        //log.info("地图ID："+mapId);
        MapBossPos mapBossPos = bossService.getMapBossPos(mapId);
        if(mapBossPos == null){
            //log.info("地图ID++："+mapId);
            mapBossPos = bossService.getMapBossPos(4000);
        }
        List<Position> list = new ArrayList<>(mapBossPos.getList());
        //       List<Position> positions = getUsedPositions(mapId);//获得已经使用的记录
//        if (positions != null) {
//            /**都被占满时，清空记录*/
//            if (list.size() == positions.size()) {
//                positions.clear();
//                log.error("{}位置已经使用完，位置总数量为:{}。开始重置!!", mapId, list.size());
//            }
//            list.removeAll(positions);
//        }

        int index = ThreadLocalRandom.current().nextInt(list.size());
        Position position = list.get(index);
        recordPosition(mapId, position);

        return position;
    }

    /**记录对应位置被使用*/
    private void recordPosition(int mapId, Position position) {
//        List<Position> positions = usedPotions.get(mapId);
//        if (positions == null) {
//            positions = new CopyOnWriteArrayList<>();
//            usedPotions.put(mapId, positions);
//        }
//        positions.add(position);
    }

    /**获得已经使用的位置*/
    private List<Position> getUsedPositions(int mapId) {
        return usedPotions.get(mapId);
    }

    /**清除之前的已使用记录*/
    protected void removeUsedPosition(int mapId, int x, int y) {
//        List<Position> positions = usedPotions.get(mapId);
//
//        for (Position position : positions) {
//            if (position.getX() == x && position.getY() == y) {
//                positions.remove(position);
//                break;
//            }
//        }
    }

    public void sendNpcContent(Role role, NPC bossNpc) {
        String content = getNpcContent(role, bossNpc);
        sendNpcContent(role, bossNpc, content);
    }

    public void startFight(Role role, NPC bossNpc) {
        /**判断是否可以战斗*/
        String content = getNpcContentNotFight(role, bossNpc);

        if (content != null) {
            sendNpcContent(role, bossNpc, content);
            return ;
        }

        /**检测不在战斗时，触发战斗。并设置NPC为战斗状态*/
        if (!isSetInFight() || bossNpc.getInFight().compareAndSet(false, true)) {
            /**触发战斗1*/
            doStartFight(role, bossNpc);
        }
    }

    public void sendNpcContent(Role role, NPC bossNpc, String content) {
        SpringUtils.getNpcService().sendNpcContent(role, bossNpc, content);
        // 这里会覆盖掉content的内容，而是继续显示原有NPC的内容。此行注释，有bug
        // SpringUtils.getNpcService().sendPurNpcContent(role, bossNpc, content);


    }


    /**是否需要设置战斗状态，保证只有一个进入战斗*/
    public boolean isSetInFight() {
        return true;
    }

    public void handleFightEnd(FightEndEvent fightEndEvent) {
        /**事件应该是在战斗线程触发的，在玩家线程中处理玩家逻辑*/
        ThreadLocalUtil.addLocalTask(fightEndEvent.getRole(), () -> doFightEnd(fightEndEvent.getRole(), fightEndEvent));
    }

    public void doFightEnd(Role role, FightEndEvent fightEndEvent) {
        try {
            /**在组队又不是队长时返回*/
          //  logger.error("结束战斗111=endFight={}|{}|{}|{}", role.getUid(), fightEndEvent.getNpcId(), fightEndEvent.getFightType(), fightEndEvent.getStatus());
            if (teamService.isInTeam(role) && !teamService.isTeamLeader(role)) {
                return ;
            }
           // logger.error("结束战斗222=endFight={}|{}|{}|{}", role.getUid(), fightEndEvent.getNpcId(), fightEndEvent.getFightType(), fightEndEvent.getStatus());
            if (!isMatchFightType(role, fightEndEvent.getFightType())) {
                return ;
            }

           // logger.info("fightEndEvent={}", fightEndEvent.getStatus());
            switch (fightEndEvent.getStatus()) {
                case FightEndEvent.WIN:
                    doFightWin(role, fightEndEvent);
                    break;
                case FightEndEvent.FAIL:
                    doFightFail(role, fightEndEvent);
                    break;
                case FightEndEvent.RUNAWAY:
                    doFightRunAway(role, fightEndEvent);
                    break;
                case FightEndEvent.MAXROUND:
                    doFightMaxRound(role, fightEndEvent);
                    break;
            }
           // logger.error("结束战斗=endFight={}|{}|{}|{}", role.getUid(), fightEndEvent.getNpcId(), fightEndEvent.getFightType(), fightEndEvent.getStatus());
        } catch (Exception e) {
            log.error(role.getUid() +"|" + this.getClass().getSimpleName() +"|" + e.getMessage(), e);
        }
    }

    /**是否匹配战斗类型*/
    private boolean isMatchFightType(Role role, int fightType) {
       // logger.info("getFightType(role)={}", getFightType(role));
        return getFightType(role) == fightType;
    }

    /**处理战斗胜利*/
    public void doFightWin(Role role, FightEndEvent fightEndEvent) {
       // logger.info("getFightType={}", fightEndEvent.getFightType());
       // logger.info("getFightType(role)={}", getFightType(role));
        if (!isMatchFightType(role, fightEndEvent.getFightType())) {
            return ;
        }

        //logger.info("npcId={}", JSONUtils.toJSONString(fightEndEvent.getNpcId()));
        NPC bossNpc = getBossNpc(fightEndEvent.getNpcId());
        /**NPC不存在时，则返回*/
        if (bossNpc == null) {return ;}

        /**胜利后NPC消失*/
        clearNpcAfterWin(role, bossNpc);
        setNotInFight(role, bossNpc);

        if (teamService.isInTeam(role)) {
            Team team = teamService.getTeam(role.getRoleId());
            doFightWinForTeam(team, fightEndEvent, bossNpc);
        } else {
            doFightWinForSingle(role, fightEndEvent, bossNpc);
        }
    }

    public void doFightWinForTeam(Team team, FightEndEvent fightEndEvent, NPC bossNpc) {
        int leaderRoleId = team.getLeaderRoleId();
        ArrayList<Member> members = team.getList();
        for (Member member : members) {
            /**不知道有没可能出现null的情况*/
            if (member == null) {continue;}
            /**成员暂离时，不对其进行操作*/
            if (!member.isInTeam()) {continue;}

            if (leaderRoleId != member.getRoleId()) {
                /**其他队员需要加到玩家所在线程中处理*/
                Role role = SpringUtils.getRoleService().getPlayerBy(member.getUid());
                if(role==null){
                   continue;
                }
                ThreadLocalUtil.addLocalTask(role, () -> doFightWinForSingle(role, fightEndEvent, bossNpc));
            }
        }

        /**最后处理队长的*/
        /**现在就是在队长的线程，所以可以直接处理*/
        Role role = SpringUtils.getRoleService().getOnlinePlayer(leaderRoleId);
        doFightWinForSingle(role, fightEndEvent, bossNpc);
    }

    public void doFightWinForSingle(Role role, FightEndEvent fightEndEvent, NPC bossNpc) {
        try {
            /**给奖励*/
            //log.info("战斗结束，战斗信息222222：");
            role.pushTempCache("drop_monster_name", bossNpc.getName());
            giveReward(role, fightEndEvent, bossNpc);
            role.popTempCache("drop_monster_name");
            log.info("[ACTIVITY]|giveReward|{}|{}|{}|{}|{}|{}", role.getUid(), fightEndEvent.getNpcId(), fightEndEvent.getFightType(), fightEndEvent.getStatus(), Json.toJson(fightEndEvent.getReward(), JsonFormat.compact()));
        } catch (Exception e) {
            log.error(role.getUid() +"|" + this.getClass().getSimpleName() +"|" + e.getMessage(), e);
        }
    }

    /**处理战斗失败*/
    public void doFightFail(Role role, FightEndEvent fightEndEvent) {
        fail(role, fightEndEvent);
    }

    /**处理战斗逃跑*/
    public void doFightRunAway(Role role, FightEndEvent fightEndEvent) {
        fail(role, fightEndEvent);
    }

    private void fail(Role role, FightEndEvent fightEndEvent) {
        NPC bossNpc = getBossNpc(fightEndEvent.getNpcId());
        if (bossNpc == null) {return ;}

        setNotInFight(role, bossNpc);
        if (bossNpc.getEndTime() > 0 && System.currentTimeMillis() > bossNpc.getEndTime()) {
            clearNpcTimeOut(bossNpc);
        }
    }

    /**设置npc状态为不在战斗中*/
    public void setNotInFight(Role role, NPC bossNpc) {
        if (bossNpc != null) {
            bossNpc.getInFight().set(false);
        }
    }

    /**处理战斗超过最大回合数*/
    public void doFightMaxRound(Role role, FightEndEvent fightEndEvent) {

    }

    @Override
    public void handleRoleExpire(Role role) {
        Fight fight = SpringUtils.getFightService().getFightByRoleId(role.getRoleId());
        if (fight == null) {return ;}
        if (!isMatchFightType(role, fight.getType())) {
            return ;
        }

        super.handleRoleExpire(role);

        NPC npc = null;
        if (fight != null) {
            npc = SpringUtils.getMapService().getNpc(fight.getNpcId());
        }

        doRoleExpire(role, fight, npc);
    }

    public void doRoleExpire(Role role, Fight fight, NPC npc) {
        TeamService teamService = SpringUtils.getTeamService();
        /**没组队或者队伍只有1人时*/
        if (teamService.getTeamCount(role) <= 1) {
            if (npc != null) {
                if (npc.isInFight()) {
                    setNotInFight(role, npc);
                }

                if (npc.getEndTime() > 0 && System.currentTimeMillis() > npc.getEndTime()) {
                    clearNpcTimeOut(npc);
                }
            }
        }
    }

    /**获得需要生成boss的数量*/
    public int getBossCount(Role role) {
        /**最多有10个*/
        int allCount = 10;
        int teamCount = SpringUtils.getBean(TeamService.class).getTeamCount(role);
        /**如果没有组队时，数量为1*/
        if (teamCount == 0) {teamCount = 1;}

        /**根据组队数量计算怪的数量*/
        int count = 0;
        if (teamCount == 5) {
            count = allCount;
        } else {
            int minCount = 4 + teamCount;
            count = ThreadLocalRandom.current().nextInt(allCount-minCount+1)  + (minCount);
        }
        return count;
    }
    /*
    这里处理首杀奖励
     */
    public void sendShouShaReward(Team team,NPC bossNpc,String title){
        String teamName = team.getMemberNames();
        //经过不懈的努力，XXX成为了本区组首支成功挑战魔龙之尾的队伍，为表彰其功绩特奖励以上道友:90枚召唤令·十二生肖、20枚召唤令·上古神兽。
        String msg = "经过不懈的努力，#Y%s#n成为了本区组首支成功挑战#Y%s#n的队伍，为表彰其功绩特奖励以上道友:#R30#n枚#R召唤令·十二生肖#n、#R10#n枚#R召唤令·上古神兽#n。";
        msg = String.format(msg,teamName,bossNpc.getName());
        chatService.sendAdnotice(msg);
        for (Member member : team.getList()) {
            Mail mail = SpringUtils.getMailService().createMail("首杀奖励", "击杀"+bossNpc.getName(), 7 * TimeUtil.ONE_DAY);
            ArrayList<NutMap> maps = new ArrayList<>();
            maps.add(new NutMap().setv("data", "#I物品|召唤令·上古神兽#r10#I").setv("type", Const.rewardWupin));
            maps.add(new NutMap().setv("data", "#I物品|召唤令·十二生肖#r30#I").setv("type", Const.rewardWupin));
            mail.getDatas().addAll(maps);
            Role teamRole = SpringUtils.getRoleService().getPlayerBy(member.getRoleId());
            SpringUtils.getMailService().sendNewMail(teamRole, mail);
        }

    }
    public void addRoleBossImg(Role role,BossImgType bossImgType){
        BossImgInfos bossImgInfos = role.getExtendBox().getBossImgInfos();
//        bossImgInfos.setMagPower(bossImgInfos.getMagPower()+500);
//        bossImgInfos.setPhyPower(bossImgInfos.getPhyPower()+800);
//        bossImgInfos.setMaxLife(bossImgInfos.getMaxLife()+1200);
        NutMap bossImgMap = bossImgInfos.getBossImgMap();
        int anInt = bossImgMap.getInt(bossImgType.getActivityId(),1);
        if(anInt<2){
            bossImgMap.put(bossImgType.getActivityId(),2);
        }
    }
}
